﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DevToolBox.Common;
using DevToolBox.Cloud.Common;
using DevToolBox.Cloud.Amazon;
using DevToolBox.Cloud.Azure;
using DevToolBox.Cloud.Local;

namespace DevToolBox.Cloud.Factory
{
    /// <summary>
    /// Object to initialize cloud-specific service clients.
    /// This class implements the multiton design pattern
    /// </summary>
    public static class CloudFactory
    {
        private static ICacheable cacheClient = null;
        private static IEFClient efClient = null;
        private static IManageable operationsQueueClient = null;
        private static IQueueable queueClient = null;
        private static ITableCommand queryExecClient = null;
        private static IManageable transactionQueueClient = null;
        private static IDownloadable downloadTransactionClient = null;
        private static IManageable downloadOperationsClient = null;
        private static IManageable platformKeysClient = null;

        public static IManageable BuildPlatformKeysClient()
        {
            if (platformKeysClient == null)
            {
                platformKeysClient = new AmazonIdentityManagement();
            }
            return platformKeysClient;
        }

        /// <summary>
        /// Function to build a new Queue Manager
        /// </summary>
        /// <remarks>
        /// The new instance does queue operations, not queue transactions
        /// Currently, only Amazon is supported.
        /// </remarks>
        /// <returns>Specific IManageable implementation</returns>
        public static IManageable BuildOperationsQueue()
        {
            if (operationsQueueClient == null)
            {
                string serverAddress = ConfigParamReader.GetString("ServerAddress");
                operationsQueueClient = new AmazonSQSOperations("http://" + serverAddress);
            }
            return operationsQueueClient;
        }

        /// <summary>
        /// Function to Build an Entity Framework like client
        /// </summary>
        /// <remarks>Only Amazon DynamoDb is supported</remarks>
        /// <returns>Specific IEFClient implementation</returns>
        public static IEFClient BuildEFClient()
        {
            if (efClient == null)
            {
                efClient = new DynamoDbEF();
            }
            return efClient;
        }

        /// <summary>
        /// Function to build a Queue transactions client
        /// </summary>
        /// <remarks>
        /// The returned object does transactions, not operations
        /// </remarks>
        /// <returns>Specific IQueueable implementation</returns>
        public static IQueueable BuildTransactionQueue()
        {
            if (queueClient == null)
            {
                string serverAddress = ConfigParamReader.GetString("ServerAddress");
                string accountNumber = ConfigParamReader.GetString("AccountNumber");
                queueClient = new AmazonSQSTransaction("http://" + serverAddress, accountNumber);
            }
            return queueClient;
        }

        /// <summary>
        /// Function to build a Cache client
        /// </summary>
        /// <param name="logger">Logger object (for logging errors)</param>
        /// <remarks>
        /// Azure, Amazon and Local cache is supported. Local cache lasts
        /// during the applicatioon life
        /// </remarks>
        /// <returns>Specific ICacheable implementation</returns>
        public static ICacheable BuildCache()
        {
            if (cacheClient == null)
            {
                string cacheParam = ConfigParamReader.GetString("CacheClientType");
                switch (cacheParam)
                {
                    case "AZURE":
                        cacheClient = new WindowsAzureSharedCaching();
                        break;
                    case "AMAZON":
                        cacheClient = new MemCachedTransactions();
                        break;
                    case "LOCAL":
                        cacheClient = new ASPNetCache();
                        break;
                    default:
                        throw new Exception("No CacheClientType was found in the .config file");
                }
            }
            return cacheClient;
        }

        /// <summary>
        /// Function to build a Queryobject
        /// </summary>
        /// <remarks>
        /// Only Amazon DynamoDb is supported
        /// The returned object can query/scan/put elements but using simple
        /// parameters. Does not use an object based approach (i.e. IEFClient)
        /// </remarks>
        /// <returns>Specific IQueryExecutor implementation</returns>
        public static ITableCommand BuildTableTransactions()
        {
            if (queryExecClient == null)
            {
                string cacheParam = ConfigParamReader.GetString("TableStorageType");
                switch (cacheParam)
                {
                    case "AZURE":
                        queryExecClient = new TableStorageTransactions();
                        break;
                    case "AMAZON":
                        queryExecClient = new DynamoDb();
                        break;
                }
            }
            return queryExecClient;
        }

        /// <summary>
        /// Function to build an Table operations object
        /// </summary>
        /// <remarks>
        /// Only Amazon DynamoDb Operations are supported
        /// </remarks>
        /// <returns>Specific IManageable implementation</returns>
        public static IManageable BuildTableOperations()
        {
            if (transactionQueueClient == null)
            {
                string cacheParam = ConfigParamReader.GetString("TableStorageType");
                switch (cacheParam)
                {
                    case "AZURE":
                        transactionQueueClient = new TableStorageOperations();
                        break;
                    case "AMAZON":
                        transactionQueueClient = new DynamoTableOperations();
                        break;
                }
            }
            return transactionQueueClient;
        }

        public static IDownloadable BuildDownloadTransactions()
        {
            if (downloadTransactionClient == null)
            {
                downloadTransactionClient = new AmazonS3Transactions();
            }
            return downloadTransactionClient;
        }

        public static IManageable BuildDownloadOperations()
        {
            if (downloadOperationsClient == null)
            {
                downloadOperationsClient = new AmazonS3Operations();
            }
            return downloadOperationsClient;
        }
    }
}
